home *** CD-ROM | disk | FTP | other *** search
- /*
- * Objects-In-C test program
- *
- * Copyright © John Wainwright 1988
- *
- */
-
- #include "oic.h"
- #include "generics.h"
- #include "names.h"
-
- enum { TITLE = 1, BOUNDS, KIND };
- extern class Window;
-
- main()
- {
- object p1, p2, n1, n2, n3, n4;
- object box1, box2;
- object list1, list2, s1;
- object seq, item;
- register int i;
- register long time;
- extern class Coord, Box, Window;
- object d, w;
- static Rect bounds = {100, 100, 350, 350};
- GenericTable *gen;
-
- MaxApplZone();
-
- /*
- * initialize OIC.
- */
- InitOIC();
- InitSysClasses();
- InitTestClasses();
- InitNameClasses();
-
- /*
- TraceClass(List);
- TraceOn();
- */
-
- /*
- * play with strings & lists. This code exercises the object
- * making routines. It makes a few strings & lists of strings
- * & uses the generic "print" to dump them out.
- */
-
- print(New(String, "hello world"));
- list1 = New(List,
- New(String, "one"),
- New(String, "two"),
- s1 = New(String, "three"), END);
- print(list1);
- print(head(list1));
- print(tail(list1));
- print(list1);
- print(add(list1, New(String, "four"),
- New(List,
- New(String, "one"),
- New(String, "two"),
- New(String, "three"), END), END));
-
- /*
- * ditto with Coords & Boxes - these are just some silly little
- * classes for the test program to play with. I wouldn't make
- * real Point & Rect classes using OIC - you need extremely high
- * bandwidth in manipulating them they're best left as C types
- */
-
- print((p1 = New(Coord, 100.0, 100.0)));
- offset(p1, 2.0, 4.0);
- print(p1);
- p2 = New(Coord, 200.0, 200.0);
- print((box1 = New(Box, 100.0, 100.0, 200.0, 200.0)));
-
- /*
- * add different things to the original list - here we are
- * showing the heterogeneous nature of List - it can contain any
- * class of object as an element.
- */
- add(list1, p1, box1, New(List, box1, p1, END), END);
- print(list1);
- print(push(list1, p1));
- print(list1 = delete(list1, p1));
- print(list1 = delete(list1, s1));
- gprintf(screen, "%s %s\n", ClassNameOf(list1), ClassNameOf(p1));
-
- /*
- * experiment with the sequencing class. This is an
- * EXTREMELY powerful generic sequencing mechanism
- * that fits cleanly with the C for statement. Any class
- * that responds to the "sequence" generic can be thusly
- * sequenced over.
- */
-
- for (seq = sequence(list1); item = next(seq);)
- print(item);
-
- /*
- * the above can be done more simply using the "map" generic,
- * inherited from "Object". It maps a function over each element
- * (using the "sequence" generic) of the given object.
- */
-
- map(list1, print);
-
- /*
- * "Coords" inherit from indexMixin which keeps track of
- * all instances - it provides a class method for "sequence"
- * to allow us to simply sequence over all instances.
- * see how neat it all is ?
- */
- gprintf(screen, "\nall Coord instances...\n");
- for (seq = sequence(Coord); item = next(seq);)
- {
- gprintf(screen, "-> "); print(item);
- }
-
- /*
- * indexMixin can find ALL its kept instances ...
- */
- gprintf(screen, "\nall indexMixin deepinstances...\n");
- for (seq = sequence(deepInstances(IndexMixin)); item = next(seq);)
- {
- gprintf(screen, "-> "); print(New(List, item, className(item), END));
- }
-
- /*
- * playing with other kind of list
- */
- gprintf(screen, "\ntrying alternate list classes...\n");
- list2 = New(List2);
- add(list2, New(String, "one"),
- New(String, "two"),
- New(String, "three"), END);
- print(list2);
-
- /*
- * timing differences in making the 2 different list kinds.
- * OIC is reasonably quick - here we have a 1000 element list being
- * created & then sequenced through in about a second on a Mac II.
- * Profiling has shown that about 45% of the time is spent (not
- * suprisingly) in the mehtod dispatch function "Method". Recoding
- * it in assembler could bring substantial improvements.
- */
- gprintf(screen, "\nmaking a 1000 element list\n");
- time= TickCount();
- list1 = New(List, END);
- for (i = 0; i < 1000; i++)
- push(list1, p1);
- gprintf(screen, "done... sequencing it...\n");
- for (i = 0, seq = sequence(list1); item = next(seq); )
- i++;
- gprintf(screen, "done, found %d items, %ld ticks\n", i, TickCount() - time);
-
- gprintf(screen, "making a 1000 element list2\n");
- time= TickCount();
- list2 = New(List2);
- for (i = 0; i < 1000; i++)
- push(list2, p1);
- gprintf(screen, "done... sequencing it...\n");
- for (i = 0, seq = sequence(list2); item = next(seq); )
- i++;
- gprintf(screen, "done, found %d items, %ld ticks\n", i, TickCount() - time);
-
- /*
- * the class Class has a number of useful methods ...
- */
- gprintf(screen, "\nall Object subclasses...\n");
- print(subs(Object));
-
- gprintf(screen, "all Collect subclasses...\n");
- print(subs(Collect));
-
- gprintf(screen, "all List2 supers...\n");
- print(supers(List2));
-
- /*
- * check out the fledgling imbedded Lisp classes ....
- * at the moment only the early name space classes are present
- * in rough form. The HashTable, NameSpace, & Name classes might be
- * useful on their own.
- */
-
- p1 = New(NameSpace, 127, 0);
- print(p1);
- n1 = declare(Name, "fred");
- print(n1);
- bind(p1, n1, New(List, New(String, "123"), END));
- print(p1);
- print(get(p1, n1));
- gprintf(screen, "%lx, %lx, %lx\n", n1, declare(Name, "fred"), declare(Name, "Joe"));
- bind(p1, declare(Name, "Bill"), box1);
-
- for (seq = sequence(p1); item = next(seq); )
- {
- gprintf(screen, "%s: ", stringOf(item));
- print(get(p1, item));
- }
-
- /*
- * play around with the very simple window class. Note that
- * it uses List as a mixin to provide a simple contents list.
- * I am also experimenting with keyword parameters, a la Lisp -
- * see window.c see & key_arg() in oic.h for details
- */
- w = New(Window, BOUNDS, &bounds,
- TITLE, "\pJohn's",
- KIND, (long)rDocProc,
- END);
-
- add(w, box1, New(Box, 150.0, 150.0, 190.0, 190.0), END);
- draw(w);
- print(w);
-
- /*
- * check the DependentsMixin class. It is intended as a
- * change propgation system. Class Box inherits from
- * DependentsMixin: any instance can have dependents declared.
- */
- gprintf(screen, "check change propogation\n");
- box2 = New(Box, 10.0, 10.0, 20.0, 20.0);
- addDependent(box2, box1);
- offset(box2, 1.0, 4.0);
-
- /*
- * check the "cantDo", "CanYouDo" mechanism
- */
- gprintf(screen, "check the cantDo mehcanism\n");
- append(s1);
- next(list1);
-
- gprintf(screen, "%s append\n", CanYouDo(s1, appendGeneric) ? "I can do " : "I can't do ");
- gprintf(screen, "%s equal\n", CanYouDo(s1, equalGeneric) ? "I can do " : "I can't do ");
-
- /*
- * print the list of generics
- */
-
- gprintf(screen, "the generics ...\n\n");
- for (i = 0, gen = generics; gen != NULL; i++, gen = gen->gen_next)
- gprintf(screen, "%d: %s()\n", i, GenericName(gen));
-
- gprintf(screen, "all done\n");
- }
-
- InitTestClasses()
- {
- InitCoordClass();
- InitBoxClass();
- InitWindowClass();
- }
-